package plus.easydo.starter.jpa.utils;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;

/**
 * @author yuzhanfeng
 * date 2021-1-28 14:33:10
 * 数据查询条件拼接工具类
 */
public class JPAUtil {

    public static void equals(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value) {
        equals(predicates, cb, root, colmun, value, colmun);
    }

    public static void notEqual(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value) {
        notEqual(predicates, cb, root, colmun, value, colmun);
    }

    public static void equals(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.equal(root.get(colmun), value));
    }

    public static void notEqual(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.notEqual(root.get(colmun), value));
    }

    public static void likeLeft(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value) {
        likeLeft(predicates, cb, root, colmun, value, colmun);
    }

    public static void likeLeft(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.like(root.get(colmun), "%" + value));
    }

    public static void likeRight(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value) {
        likeRight(predicates, cb, root, colmun, value, colmun);
    }

    public static void likeRight(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.like(root.get(colmun), value + "%"));
    }

    public static void like(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value) {
        like(predicates, cb, root, colmun, value, colmun);
    }

    public static void like(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.like(root.get(colmun), "%" + value + "%"));
    }

    public static void isNull(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun) {
        predicates.add(cb.isNull(root.get(colmun)));
    }

    public static void isNotNull(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun) {
        predicates.add(cb.isNotNull(root.get(colmun)));
    }

    public static void between(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Integer min, Integer max) {
        predicates.add(cb.between(root.get(colmun), min, max));
    }

    public static void in(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value) {
        if (!checkvalue(colmun, value)) {
            return;
        }
        List<?> list = (List<?>) value;
        CriteriaBuilder.In<Object> in = cb.in(root.get(colmun));
        for (int i = 0; i < list.size(); i++) {
            in.value(list.get(i));
        }
        predicates.add(in);
    }

    public static void notIn(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, Object value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        List<?> list = (List<?>) value;
        CriteriaBuilder.In<Object> in = cb.in(root.get(colmun));
        for (int i = 0; i < list.size(); i++) {
            in.value(list.get(i));
        }
        predicates.add(cb.not(in));
    }

    private static boolean checkvalue(String valueKey, Object value) {
        if (value != null) {
            if (value instanceof String) {
                return !Validator.isEmpty(value);
            } else if (value instanceof List) {
                if (((List) value).isEmpty()) {
                    return false;
                }
            }
        } else {
            return false;
        }
        return true;
    }

    public static void greaterTo(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.greaterThanOrEqualTo(root.get(colmun), value));
    }

    public static void greaterToDate(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.greaterThanOrEqualTo(root.get(colmun), DateUtil.parseDateTime(value)));
    }

    public static void greaterThanOrEqualTo(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value) {
        greaterThanOrEqualTo(predicates, cb, root, colmun, value, colmun);
    }

    public static void greaterThanOrEqualTo(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.greaterThanOrEqualTo(root.get(colmun), value));
    }

    public static void lessTo(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.lessThanOrEqualTo(root.get(colmun), value));
    }

    public static void lessThanOrEqualTo(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value) {
        lessThanOrEqualTo(predicates, cb, root, colmun, value, colmun);
    }

    public static void lessThanOrEqualTo(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.lessThanOrEqualTo(root.get(colmun), value));
    }

    public static void lessThanOrEqualToDate(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.lessThanOrEqualTo(root.get(colmun), DateUtil.parseDateTime(value)));
    }


    public static void greaterThanOrEqualToDate(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.greaterThanOrEqualTo(root.get(colmun), DateUtil.parseDateTime(value)));
    }

    public static void lessToDate(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value, String valueKey) {
        if (!checkvalue(valueKey, value)) {
            return;
        }
        predicates.add(cb.lessThanOrEqualTo(root.get(colmun), DateUtil.parseDateTime(value)));
    }

    public static void lessThanOrEqualToDate(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value) {
        lessThanOrEqualToDate(predicates, cb, root, colmun, value, colmun);
    }

    public static void greaterThanOrEqualToDate(List<Predicate> predicates, CriteriaBuilder cb, Root<?> root, String colmun, String value) {
        greaterThanOrEqualToDate(predicates, cb, root, colmun, value, colmun);
    }
}
